package com.qlogic.commons;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.qlogic.commons.exceptions.BaseRuntimeException;

public abstract class StandardLogger implements AbstractLogger {

	protected int logType = DEBUG;
	
	protected AbstractLogger logger;
	
	private static Map<String, AbstractLogger> loggersCache = new HashMap<String, AbstractLogger> ();
	
	public StandardLogger () {
		String loggerClassName = System.getProperty (LOGGER);
		if (loggerClassName != null) {
			logger = loggersCache.get (loggerClassName);
			if (logger == null) {
				ClassLoader classLoader = Thread.currentThread ().getContextClassLoader ();
				if (classLoader == null) {
					classLoader = StandardLogger.class.getClassLoader ();
				}
				try {
					logger = (AbstractLogger)classLoader.loadClass (loggerClassName).newInstance ();
				} catch (Exception e) {
					throw new BaseRuntimeException (e);
				} 
				loggersCache.put (loggerClassName, logger);
			}
		} else {
			logger = this;
		}
	}

	public void setLogType(int logType) {
		this.logType = logType;
	}

	public int getLogType() {
		return logType;
	}

	public void console(Object message, int logType) {
		if (logger.equals (this)) {
			if (logType >= this.logType) {
				String messageType = getLogLabel(logType);
				String msg = (message == null) ? "NULL" : message.toString();
				if (logType == WARNING || logType == ERROR) {
					System.err.println("[" + new Date () + " | " + getLoggerName() + "-" + messageType
							+ "] --> " + msg);
				} else {
					System.out.println("[" + new Date () + " | " + getLoggerName() + "-" + messageType
							+ "] --> " + msg);
				}
			}
		} else {
			if (logger.getLoggerName () == null) {
				logger.setLoggerName (getLoggerName ());
			}
			if (logType >= this.logType) {
				logger.console (message, logType);
			}
		}
	}

	public void console(Object message) {
		console(message, DEBUG);
	}	

	private String getLogLabel(int logType) {
		switch (logType) {
		case DEBUG:
			return "DEBUG";
		case WARNING:
			return "WARNING";
		case ERROR:
			return "ERROR";
		case INFO:
			return "INFO";
		default:
			return "INFO";
		}
	}

}